package com.ysl.netty.handler;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ysl.netty.common.SessionSocket;
import com.ysl.netty.domain.SentBody;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.List;
import java.util.UUID;

/**
 * @author 姚善利
 * @classname com.ysl.netty.handler
 * @description
 * @date 2022/7/8 16:00
 */
public class ServerHandler extends SimpleChannelInboundHandler<Object> {

    /**
     * 读取客户端发过来的请求，并且向客户端返回响应的方法
     *
     * @param ctx 上下文，可以获取远程的信息，地址、连接对象
     * @param msg 客户端发来的请求对象
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        String message="";
        if(msg instanceof TextWebSocketFrame)
        {
            message=((TextWebSocketFrame)msg).text();

            JSONObject json = JSONObject.parseObject(message);
            if (json.containsKey("type")) {
                String type = json.getString("type");
                if (type.equals("login")) {
                    String userid = json.getString("key");
                    List<String> listclient = SessionSocket.likeRedisTemplate.getOnline();
                    for (int i = 0; i < listclient.size(); i++) {
                        String cid=listclient.get(i);
                        Channel channel= SessionSocket.likeRedisTemplate.getChannel(cid);

                        channel.writeAndFlush(userid+"上线");
                    }
                    SessionSocket.likeRedisTemplate.saveChannel(userid, ctx.channel());
                }

                if (type.equals("ping")) {

                }
            }
        }
        else if(msg instanceof BinaryWebSocketFrame)
        {
            byte[] bytes=((BinaryWebSocketFrame)msg).content().array();
        }
        else if (msg instanceof String)
        {
            JSONObject json = JSONObject.parseObject(msg.toString());
            if (json.containsKey("type")) {
                String type = json.getString("type");
                if (type.equals("login")) {
                    String userid = json.getString("key");
                    List<String> listclient = SessionSocket.likeRedisTemplate.getOnline();
                    for (int i = 0; i < listclient.size(); i++) {
                        String cid=listclient.get(i);
                        Channel channel= SessionSocket.likeRedisTemplate.getChannel(cid);

                        channel.writeAndFlush(userid+"上线");
                    }

                    SessionSocket.likeRedisTemplate.saveChannel(userid, ctx.channel());
                }

                if (type.equals("ping")) {

                }
            }
        }
        else if(msg instanceof SentBody)
        {
            SentBody sentBody=(SentBody) msg;
            String type = sentBody.getType();
            if (type.equals("login")) {
                String userid = sentBody.getKey();
                List<String> listclient = SessionSocket.likeRedisTemplate.getOnline();
                for (int i = 0; i < listclient.size(); i++) {
                    String cid=listclient.get(i);
                    Channel channel= SessionSocket.likeRedisTemplate.getChannel(cid);

                    channel.writeAndFlush(userid+"上线");
                }
                SessionSocket.likeRedisTemplate.saveChannel(userid, ctx.channel());
            }

            if (type.equals("ping")) {

            }
        }
        else
        {
            System.out.println("未知消息"+msg.getClass().getName());
        }
        /*
            write 写入缓冲
            flush 把缓冲的内容清/推出去
            writeAndFlush 写入缓冲，并把缓冲的内容推出去
         */
        ctx.channel().writeAndFlush("服务的from server：" + UUID.randomUUID());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //可能出现业务判断离线后再次触发 channelInactive
        String userid = SessionSocket.likeRedisTemplate.getUserId(ctx.channel());
        if (StrUtil.isNotEmpty(userid)) {
            List<String> listclient = SessionSocket.likeRedisTemplate.getOnline();
            for (int i = 0; i < listclient.size(); i++) {
                String cid=listclient.get(i);
                Channel channel= SessionSocket.likeRedisTemplate.getChannel(cid);
                channel.writeAndFlush(userid+"下线");
            }

            SessionSocket.likeRedisTemplate.deleteChannel(userid);
            ctx.channel().close();
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            if (idleStateEvent.state() == IdleState.READER_IDLE) {

            }
        }
        super.userEventTriggered(ctx, evt);
    }

    /**
     * 出现异常的情况下怎么办
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        //GlobalChannelGroup.channelGroup.add(ch);
        //SocketChannelGroup.likeRedisTemplate.saveChannel(ch.id().asLongText(),ch);

        //System.out.println(SessionSocket.likeRedisTemplate.getOnline());
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        String userid = SessionSocket.likeRedisTemplate.getUserId(ch);
        if (StrUtil.isNotEmpty(userid)) {
            SessionSocket.likeRedisTemplate.deleteChannel(userid);
        }
        super.handlerRemoved(ctx);
    }
}
